package com.threeox.commonlibrary.eventbus;

import com.threeox.utillibrary.util.LogUtils;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 *
 * @ClassName: EventBus
 *
 * @Description: ()
 *
 * @author 赵屈犇
 *
 * @date 创建时间:2016/12/19 15:30
 *
 * @version 1.0
 */
@SuppressWarnings("rawtypes")
public class EventBus {
	public static final String TAG = "EventBus";
	private static EventBus mEventBus = null;
	private String methodName = "onEvent";

	public static Map<String, ArrayList<EventBusMsg>> mObjMaps = new HashMap<String, ArrayList<EventBusMsg>>();

	private EventBus(){}

	public static EventBus getInstance() {
		if (mEventBus == null) {
			synchronized (EventBus.class) {
				if (mEventBus == null) {
					mEventBus = new EventBus();
					LogUtils.d("初始化EventBus!");
				}
			}
		}
		return mEventBus;
	}

	/**
	 * 注册进入一个JAVA类
	 * 
	 * @param obj
	 * @return
	 */
	public EventBus register(Object obj) {
		Class cls = obj.getClass();
		ArrayList<EventBusMsg> objs = null;
		// 判断当前的类是否存在于map中
		synchronized (this) {
			if (mObjMaps.containsKey(cls)) {
				objs = mObjMaps.get(cls.getName());
			} else {
				objs = new ArrayList<EventBusMsg>();
			}
			// 将所有的onEvent 方法存入进来
			List<Method> methodEvent = new ArrayList<Method>();
			Method[] methods = cls.getMethods();
			for (Method method : methods) {
				if (method.getName().equals(methodName)) {
					methodEvent.add(method);
				}
			}
			EventBusMsg eventBusMsg = new EventBusMsg(obj, methodEvent);
			objs.add(eventBusMsg);
			mObjMaps.put(cls.getName(), objs);
		}
		return mEventBus;
	}

	public EventBus post(Object... vals) {
		Set<String> set = mObjMaps.keySet();
		for (String key : set) {
			postMethod(key, mObjMaps.get(key), vals);
		}
		return mEventBus;
	}

	/**
	 * 根据键名反射进入
	 * 
	 * @param obj
	 *            当前类的class
	 * @param vals
	 */
	public EventBus postByKey(Object obj, Object... vals) {
		String key = obj.getClass().getName();
		postMethod(key, mObjMaps.get(key), vals);
		return mEventBus;
	}

	/**
	 * 反射Method
	 * 
	 * @param eventBusMsgs
	 * @param vals
	 */
	private void postMethod(String key, ArrayList<EventBusMsg> eventBusMsgs,
			Object... vals) {
		if (eventBusMsgs != null && !eventBusMsgs.isEmpty()) {
			for (EventBusMsg eventBusMsg : eventBusMsgs) {
				List<Method> methods = eventBusMsg.getMethods();
				for (Method method : methods) {
					try {
						method.invoke(eventBusMsg.getObj(), vals);
						LogUtils.e(eventBusMsg.getObj().getClass()
								.getSimpleName()
								+ "-->onEvent注入成功!");
					} catch (IllegalArgumentException e) {
						LogUtils.e(eventBusMsg.getObj().getClass()
								.getSimpleName()
								+ "-->onEvent反射失败!");
					} catch (Exception e) {
					}
				}
			}
		} else {
			LogUtils.e(key + "这个对象已经被移除啦!");
		}
	}

	/**
	 * 移除对象
	 * 
	 * @param obj
	 * @return
	 */
	public EventBus unregister(Object obj) {
		String key = obj.getClass().getName();
		ArrayList<EventBusMsg> eventBusMsgs = null;
		synchronized (this) {
			if (mObjMaps.containsKey(key)) {
				eventBusMsgs = mObjMaps.get(key);
			}
			if (eventBusMsgs != null) {
				EventBusMsg eventMsg = null;
				for (EventBusMsg eventBusMsg : eventBusMsgs) {
					if (eventBusMsg.getObj() == obj) {
						eventMsg = eventBusMsg;
					}
				}
				if (eventMsg != null)
					eventBusMsgs.remove(eventMsg);
				mObjMaps.put(key, eventBusMsgs);
				LogUtils.e(key + "已经被移除一个对象啦!");
			}
		}
		return mEventBus;
	}

	/**
	 * 根据对象移除全部对象
	 * 
	 * @param obj
	 * @return
	 */
	public EventBus unregisterAll(Object obj) {
		String name = obj.getClass().getName();
		mObjMaps.remove(name);
		LogUtils.e("已经成功将" + name + "对象全部移除了");
		return mEventBus;
	}

	public ArrayList<EventBusMsg> getObjMaps(Class key) {
		return mObjMaps.get(key);
	}

}
